package util

import (
	"strconv"
	"strings"

	"mall/common/enumx"
	"mall/common/globalkey"
	"mall/service/backend/common/enum/common"
	"mall/service/blog/rpc/blogclient"
)

const (
	arrayValueSeparator    = ","
	keyValueSeparator      = ":"
	keyOpSeparator         = ","
	arrayKeyValueSeparator = ";"
)

func ParseSorter(sorter string) (res []*blogclient.BackendOrderBy) { //////
	sorters := strings.Split(sorter, arrayKeyValueSeparator)
	if len(sorters) > 0 {
		for _, orderBy := range sorters {
			orderBys := strings.SplitN(orderBy, keyValueSeparator, 2)
			if len(orderBys) == 2 && orderBys[0] != "" && orderBys[1] != "" {
				res = append(res, &blogclient.BackendOrderBy{
					Field: orderBys[0],
					Order: orderBys[1],
				})
			}
		}
	}

	return
}

func ParseSorterNew(sorter *string) (res []*blogclient.OrderBy) { // ##24.11.07## 完成
	if sorter == nil {
		return
	}

	sorters := strings.Split(*sorter, arrayKeyValueSeparator)
	if len(sorters) == 0 {
		return
	}

	for _, orderBy := range sorters {
		orderBys := strings.Split(orderBy, keyValueSeparator)

		if len(orderBys) == 2 && len(orderBys[0]) > 0 {
			ascOrDesc := "0"
			if len(orderBys[1]) > 0 {
				ascOrDesc = orderBys[1]
			}
			res = append(res, &blogclient.OrderBy{
				Field: orderBys[0],
				Order: ascOrDesc,
			})
			continue
		}

		if len(orderBys) == 1 && len(orderBys[0]) > 0 {
			res = append(res, &blogclient.OrderBy{
				Field: orderBys[0],
				Order: "0",
			})
		}
	}

	return
}

func ParseFilter(filter string) (res []*blogclient.BackendFilterBy) { //////
	filters := strings.Split(filter, arrayKeyValueSeparator)
	if len(filters) > 0 {
		for _, filterBy := range filters {
			filterBys := strings.SplitN(filterBy, keyValueSeparator, 2)
			if len(filterBys) == 2 && filterBys[0] != "" && filterBys[1] != "" {
				res = append(res, &blogclient.BackendFilterBy{
					Field: filterBys[0],
					In:    filterBys[1],
				})
			}
		}
	}

	return
}

func ParseFilterNew(filter *string, postType *uint32) (res []*blogclient.FilterBy) { // ##24.11.07## 完成
	if filter != nil {
		filters := strings.Split(*filter, arrayKeyValueSeparator)
		if len(filters) > 0 {
			for _, filterBy := range filters {
				filterBys := strings.Split(filterBy, keyValueSeparator)

				if len(filterBys) == 2 && len(filterBys[0]) > 0 && len(filterBys[1]) > 0 {
					res = append(res, &blogclient.FilterBy{
						Field: filterBys[0],
						In:    filterBys[1],
					})
				}
			}
		}
	}

	if postType != nil {
		res = append(res, &blogclient.FilterBy{
			Field: "type",
			In:    strconv.FormatInt(int64(*postType), 10),
		})
	}

	return
}

func ParseTaxonomy(taxonomy string) int32 { // deprecated
	var res enumx.TermTaxonomy
	switch enumx.TermTaxonomyName(taxonomy) {
	case enumx.TermTaxonomyNameCategory:
		res = enumx.TermTaxonomyCategory
	case enumx.TermTaxonomyNameTag:
		res = enumx.TermTaxonomyTag
	case enumx.TermTaxonomyNameKnowledgeBase:
		res = enumx.TermTaxonomyKnowledgeBase
	}

	return int32(res)
}

func GetStatusDisplay(status int32) (res int32, displayPublicDate bool) { ///// todo 去除
	switch enumx.PostStatus(status) {
	case enumx.PostStatusAutoDraft:
		res = int32(enumx.PostStatusDraft)
	case enumx.PostStatusFuture:
		res = int32(enumx.PostStatusPublish)
		displayPublicDate = true
	case enumx.PostStatusPrivate:
		res = int32(enumx.PostStatusPublish)
	default:
		res = status
	}

	return
}

func GetStatusText(status int32) (res string) { /////
	switch enumx.PostStatus(status) {
	case enumx.PostStatusPublish:
		res = "publish"
	case enumx.PostStatusInherit:
		res = "inherit"
	case enumx.PostStatusDraft:
		res = "draft"
	case enumx.PostStatusAutoDraft:
		res = "auto-draft"
	case enumx.PostStatusPending:
		res = "pending"
	case enumx.PostStatusFuture:
		res = "future"
	case enumx.PostStatusPrivate:
		res = "private"
	case enumx.PostStatusRejected:
		res = "reject"
	case enumx.PostStatusTrash:
		res = "trash"
	default:
		res = "draft"
	}

	return
}

type Option struct {
	CanSubmit      bool
	CanAccept      bool
	CanReject      bool
	CanRemove      bool
	CanRestore     bool
	CanForceDelete bool
}

func GetOptionByStatus(status int32) *Option { ////
	res := &Option{}

	switch enumx.PostStatus(status) {
	case enumx.PostStatusPublish, enumx.PostStatusFuture, enumx.PostStatusPrivate, enumx.PostStatusRejected:
		res.CanRemove = true
		res.CanForceDelete = true
	case enumx.PostStatusDraft, enumx.PostStatusAutoDraft:
		res.CanSubmit = true
		res.CanRemove = true
		res.CanForceDelete = true
	case enumx.PostStatusPending:
		res.CanAccept = true
		res.CanReject = true
		res.CanRemove = true
		res.CanForceDelete = true
	case enumx.PostStatusTrash:
		res.CanRestore = true
		res.CanForceDelete = true
	}

	return res
}

func GetOptionByStatusAndId(status *uint32, id uint64) *Option { //##24.12.09##
	res := &Option{}

	if id == common.DefaultCategoryId || id == common.PreservedSectionIdVersion {
		return res
	}

	if id >= common.PreservedSectionIdMin && id <= common.PreservedSectionIdMax {
		return res
	}

	if status != nil {
		switch int32(*status) {
		case globalkey.StatusDisabled:
			res.CanAccept = true
			res.CanRemove = true
		case globalkey.StatusEnabled:
			res.CanReject = true
			res.CanRemove = true
		case globalkey.StatusDeleted:
			res.CanRestore = true
		}
	}

	return res
}

func GetAuditOptionByStatus(status *uint32) *Option { //##24.12.02##
	res := &Option{}

	if status != nil {
		switch int32(*status) {
		case globalkey.PostStatusFuture, globalkey.PostStatusPrivate, globalkey.PostStatusPublish:
			res.CanRemove = true
			res.CanForceDelete = true
		case globalkey.PostStatusDraft, globalkey.PostStatusAutoDraft:
			res.CanSubmit = true
			res.CanRemove = true
			res.CanForceDelete = true
		case globalkey.PostStatusPending:
			res.CanAccept = true
			res.CanReject = true
			res.CanRemove = true
			res.CanForceDelete = true
		case globalkey.PostStatusRejected:
			res.CanRemove = true
			res.CanForceDelete = true
		case globalkey.PostStatusTrash:
			res.CanRestore = true
			res.CanForceDelete = true
		}
	}

	return res
}
